@create $thing named mapper:mapper,moo mapper @prop #xxx."all_rooms" {} rc @prop #xxx."all_exits" {} rc @prop #xxx."bad_exits" {} rc @prop #xxx."xml" {} rc @prop #xxx."help_msg" {} rc ;;#xxx.("help_msg") = {"MOO MAPPER", "Created by KRJ April 10, 2010", "Modified June 19,2010"," ", "This object is used to generate data files for use in creating maps of the MOO.", "Maps can be generated using the free yEd Graph Editor from yWorks which can be obtained here: http://www.yworks.com/en/products_yed_about.html", " Typing 'count mapper' will start the collection of room and exit data.", " When the data collection is complete the user will be asked if the room names are to be included in the labels and then given the option to print the formatted output to their screen.", " Once the output is complete it can be copied and saved as a plain text file with a .graphml suffix.", " The data is contained between", " '============ Start Graphml Data ============='", " and", " '============= End Graphml Data =============='", " ", " This text file can be used in yEd Graph Editor to generate a logical map of the MOO.", " ", " Possible 'gotchas':", " The data may overrun the output buffer of the client. I use TKMOO and have not had a problem with 2700+ line outputs, but YMMV.", " The output may overrun the network buffer resulting in lost lines. If this happens reduce the chunksize in mapper:xml_out from the default 200 to some lower value.", " The graphml formatted data is stored on a property called .xml on the Mapper. Using the command 'xml_out mapper' will print the data to the users screen. This is useful if you want to rerun the output without rerunning the collection or if you want to do the display using a different client or perhaps when the MOO is not busy. The formatted data can use up a lot of quota so don't be surprised if you suddenly can't build anything more! The 'reset mapper' command will dump the data and recover your quota."} @prop #xxx."encore" 1 rc ;;#xxx.("aliases") = {"mapper", "moo mapper"} ;;#xxx.("description") = "A black box about the size of a large dictionary labeled 'Moo Mapper'" @verb #xxx:"count" this none none @program #xxx:count "Usage: count this"; "Collect room and exit data for mapping purposes."; "If encore is set collect URL info for each room"; this.all_rooms = this.all_exits = this.bad_exits = {}; r = x = 0; player:tell("============ Map Data Collection ============"); player:tell("Collecting Room Data..."); start_time = time(); allrooms = $object_utils:descendants_suspended($room); for room in (allrooms) r = r + 1; name = room.name; $command_utils:suspend_if_needed(2); if (this.encore) base_url = $encore_web_utils:baseurl(); object = toint(room); url = base_url + tostr(object); else url = ""; endif record = {room, room.name, url}; this.all_rooms = {@this.all_rooms, record}; endfor player:tell("Done total of ", r, " rooms identified"); player:tell(" "); player:tell("Collecting Exit Data..."); allexits = $object_utils:descendants_suspended($exit); for exit in (allexits) $command_utils:suspend_if_needed(5); exit_dest = exit.dest; exit_src = exit.source; exit_nam = exit.name; "Check to make sure exit goes somewhere sane, if not store it in .bad_exits"; record = {exit, exit_dest, exit_src, exit_nam}; if ((exit_dest in allrooms) && (exit_src in allrooms)) this.all_exits = {@this.all_exits, record}; x = x + 1; else this.bad_exits = {@this.bad_exits, record}; endif endfor end_time = time(); duration = end_time - start_time; player:tell("Done total of ", x, " validated exits identified"); player:tell("Data collection complete in ", duration, " seconds."); this:format_xml(this); if ($command_utils:yes_or_no("Would you like to display the xml data now?")) this:xml_out(this, "is", 200); else player:tell("The xml data can be printed out later using the command 'xml_out mapper'"); endif "Last modified Sun Apr 11 13:33:11 2010 EST by Kevinj (#331)."; . @verb #xxx:"format_xml" this none none rxd @program #xxx:format_xml "Usage: format_xml this"; "Formats the list of rooms and exits into a graphml formatted list."; "The list is stored in the property .xml"; xml = nodes = edges = this.xml = {}; if (!this.all_rooms) player:tell("There is no room data yet please run the command 'count mapper' first."); return; endif player:tell(" "); player:tell("Formatting room and exit data for use with a graphml interpreter."); if ($command_utils:yes_or_no("Do you want to include the room names in the labels?")) room_label = 1; else room_label = 0; endif start_time = time(); header = {" "}; for room in (this.all_rooms) $command_utils:suspend_if_needed(1); node = room[1]; if (room_label) "Strip out forbidden characters in the room name"; room_name = $string_utils:strip_chars(room[2], "<>&"); label = tostr(node, " ", room_name); else label = tostr(node); endif record = tostr("", label, ""); nodes = {@nodes, record}; endfor for exit in (this.all_exits) $command_utils:suspend_if_needed(1); record = tostr(""); edges = {@edges, record}; endfor footer = {""}; this.xml = $list_utils:append(header, nodes, edges, footer); end_time = time(); duration = end_time - start_time; player:tell("Formatting complete in ", duration, " seconds."); player:tell("============================================="); return; "Last modified Sun Apr 11 13:33:11 2010 EST by Kevinj (#331)."; . @verb #xxx:"xml_out" this none none rxd @program #xxx:xml_out "Usage: xml_out mapper"; "Prints the formatted xml data to the users screen"; "If the network buffer overflows choose a smaller value than the suggested 'chunksize' of 200 lines."; chunksize = 200; max_lines = length(this.xml); player:tell("Max_lines=", max_lines); chunks = max_lines / chunksize; player:tell("Total number of chunks to display ", chunks); player:tell(" "); player:tell("============ Start Graphml Data ============="); player:tell(" "); c = 0; for index in [1..max_lines] c = c + 1; if (c > chunksize) suspend(2); c = 0; endif player:tell(this.xml[index]); $command_utils:suspend_if_needed(2); endfor player:tell(" "); player:tell("============= End Graphml Data =============="); return; "Last modified Sun Apr 11 13:33:11 2010 EST by Kevinj (#331)."; . @verb #xxx:"reset" this none none @program #xxx:reset "Usage: reset mapper"; "Deletes the collected room and exit data and removes the fomatted xml data."; prompt = tostr("Are you sure you want to reset the ", this.name); if ($command_utils:yes_or_no(prompt)) this.xml = this.all_rooms = this.all_exits = this.bad_exits = {}; player:tell(this.name, " data has been reset."); return; endif player:tell(this.name, " data has not been reset."); "Last modified Sun Apr 11 13:33:11 2010 EST by Kevinj (#331)."; .